<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Ruby Socket Programming and Threads: Ruby Study Notes - Best Ruby Tutorial</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="Ruby Socket Programming and Threads: Ruby Study Notes - Best Ruby Tutorial" />
<meta name="keywords" content="ruby sockets,ruby threads,ruby networking,ruby net::smtp" />
<meta name="Distribution" content="Global" />
<meta name="author" content="Satish Talim / Original design: Erwin Aligam - ealigam@gmail.com" />
<meta name="copyright" content="Satish Talim 2007 and beyond..." />
<meta name="verify-v1" content="rFu86se+IkbtF+bH8mgJBKwU5HnKaSd8Ghw9umXQOkM=" />
<meta name="robots" content="index,follow" />
<meta http-equiv="Expires" content="0" />
<meta name="revisit-after" content="1 days" />
<link rel="stylesheet" href="/images/NewOrange.css" type="text/css" />
<link rel="stylesheet" href="/images/syntaxhighlighter.css" type="text/css" />
<link rel="icon" type="image/ico" href="/images/favicon.ico" />
<!-- Google +1 button code -->
<link rel="canonical" href="/satishtalim/ruby_socket_programming.html" />
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>

<!-- Google Analytics code -->
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-59044-10']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>
<!-- Google Analytics code ends -->
</head>

<body>
<!-- wrap starts here -->
<div id="wrap">

    <div id="header">

        <h1 id="logo">Ruby<span class="orange">Learning.github.io</span></h1>
        <h2 id="slogan">Helping Ruby Programmers become Awesome!</h2>

    </div>

    <div id="menu">
        <ul>
            <li><a href="/" title="Home page for rubylearning.github.io">Home</a></li>
            <li><a href="/satishtalim/tutorial.html" title="Get started Learning Ruby here...">Tutorial</a></li>
            <li><a href="/download/downloads.html" title="Download this tutorial as an eBook">Downloads</a></li>
            <li><a href="/other/testimonials.html" title="People around the world who benefited from this site">Testimonials</a></li>
            <li><a href="/other/certification.html" title="Get certified in Ruby">Certification</a></li>
            <li><a href="/satishtalim/ruby_guide.html" title="Ruby Guide, Mentor">Mentor</a></li>
            <li><a href="https://blog.rubylearning.github.io/" title="Ruby blog of Learning Ruby site">Blog</a></li>
            <li><a href="/satishtalim/tutorial.html" title="Online Ruby Course">Online Course</a></li>
            <li><a href="http://ruby-challenge.rubylearning.github.io/" title="Ruby Programming Challenge for Newbies">Challenge</a></li>
            <li><a href="/satishtalim/about.html" title="Information about Satish Talim">About</a></li>
        </ul>
    </div>

    <!-- content-wrap starts here -->
    <div id="content-wrap">

            <div id="main">

                <div id="main-inner"><a name="TemplateInfo"></a>
                <h1>Socket Programming and Threads</h1>

                <!--
                <div class="container">
                  <div class="adsense">
                  <strong>Note: Have added a brief note on Threads on 25th Nov. 2007.</strong>
                  </div>
                </div>
                -->

                <p>Networking usually implies TCP/IP, the way in which millions of machines communicate back and forth across the Internet. Network communication is conceptualized at different layers - data link, network, transport and application. The application layer is the world of telnet, FTP, email protocols, and much more.</p>

                <h3>Basic Networking</h3>

                <p>Let us talk a little bit about basic networking.<br />Our discussion of networking focuses on both sides of a <em>client-server relationship</em>. The <em>client</em> requests that some action be performed, and the <em>server</em> performs the action and responds to the client. A dedicated server spends its lifetime waiting for messages and answering them. A common implementation of the request-response model is between World Wide Web browsers and World Wide Web servers. When a user selects a Web site to browse through a browser (the client application), a request is sent to the appropriate Web server (the server application). The server normally responds to the client by sending an appropriate HTML Web page.</p>

                <h3>Port</h3>

                <p>A port is not a physical device, but an abstraction to facilitate communication between a server and a client.<br /><br />Ports are described by a 16-bit integer value. Hence, a machine can have a maximum of 65536 port numbers (ranging from 0 to 65535). The port numbers are divided into three ranges: the Well Known Ports, the Registered Ports, and the Dynamic and/or Private Ports. The Well Known Ports are those from 0 through 1023 (for example, port no. 80 is for http, port no. 25 is for smtp and so on).  The Registered Ports are those from 1024 through 49151. The Dynamic and/or Private Ports are those from 49152 through 65535.</p>

                <h3>Internet Addresses</h3>

                <p>These are the numerical host addresses that consist of four bytes such as 132.163.4.102. The IP address 127.0.0.1 (localhost) is a special address, called the local <em>loopback</em> address, which denotes the local machine.</p>
                <h3>Sockets</h3>

                <p>We shall develop sockets-based networking applications using the Ruby language. You need to have a basic familiarity with BSD-style sockets. Nowadays it is safe just to say "sockets". Previously one had to say "BSD sockets" because there were multiple socket APIs fighting for domination. Eventually, in the Unix/POSIX world the Berkeley Software Distribution (BSD) style socket API won out. Most *Nix programmers that do networking use BSD style sockets.<br /><br />If you are accustomed to programming network connections in C or C++, you will be pleasantly surprised at how easy it is to program them in the Ruby programming language.<br /><br />A socket represents a single connection between two network applications. These two applications nominally run on different computers, but sockets can also be used for inter-process communication on a single computer. Applications can create multiple sockets for communicating with each other. Sockets are bidirectional, meaning that either side of the connection is capable of both sending and receiving data.</p>

                <h3>Socket classes</h3>

                <p>Ruby has a rich and diverse set of sockets classes. These classes range from the standard <strong>Socket</strong> class (which mimics the BSD Sockets API) to more refined classes that focus on a particular protocol or application type.<br /><br />The class hierarchy of the base sockets classes is as shown below:</p>

                <p><a href="/images/socketapi.jpg" title="Socket API"><img src="/images/socketapi.jpg" alt="Socket API" /></a></p>

                <p>The above figure is from the book <em>Programming Ruby</em>.</p>

                <p>Most of the classes derive from the <strong>IO</strong> class. This means that we can use the methods of <strong>IO</strong> that are so familiar to us. The <strong>TCPSocket</strong> class supports sockets for the connection-based, reliable Transmission Control Protocol. A helper class for the creation of TCP server sockets is also available in the <strong>TCPServer</strong> class. To create a stream socket and connect it to a server, the <strong>TCPSocket</strong> class can be used. All socket classes are part of the standard library (and not part of the core classes), so to use them in your Ruby program, you must first write: <strong>require 'socket'</strong></p>

                <h3>Threads</h3>

                <p>You should refer to this quick guide on <a href="/satishtalim/ruby_threads.html">Ruby Threads</a> before you proceed to the program that follows.</p>

                <h3>The Date Time Server and Client</h3>

                <p>Now let us build a Ruby-based Date Time server and client that displays on the client computer the date and time at the dedicated server hosting location, using the Ruby socket API. Here's the code for the Date Time Server - <strong>p068dtserver.rb</strong></p>
                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                # p068dtserver.rb
                # Date Time Server - server side using thread
                # usage: ruby p068dtserver.rb
                require "socket"
                dts = TCPServer.new('localhost', 20000)
                loop do
                  Thread.start(dts.accept) do |s|
                    print(s, " is accepted\n")
                    s.write(Time.now)
                    print(s, " is gone\n")
                    s.close
                  end
                end
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p><strong>Explanation of the p068dtserver.rb code:</strong></p>

                <p>You first load the socket library with the <strong>require</strong> command. The <strong>TCPServer</strong> class is a helper class for building TCP socket servers. The <strong>TCPServer.new('localhost', 20000)</strong> statement creates a new socket identified by localhost and port number. The <strong>Thread.start</strong> creates and runs a new thread to execute instructions given in block. Any arguments passed to <strong>Thread.start</strong> are passed into the block. The <strong>dts.accept</strong> method waits for a connection on dts, and returns a new <strong>TCPSocket</strong> object connected to the caller. The <strong>Kernel.loop</strong> iterator calls the associated block do..end) forever (or at least until you break out of the loop). We use <strong>s.write(Time.now)</strong> to write the current date and time on the server to the socket. Finally, we write <strong>s.close</strong> to close a socket using the <strong>close</strong> method. This method is inherited from the <strong>IO</strong> class, but it's available for each of the socket types.</p>

                <p><strong>Running the server</strong></p>

                <p>Since we are testing these programs on our local machine, open a new command window, go to the folder containing your <strong>p068dtserver.rb</strong> program and type <strong>ruby p068dtserver.rb</strong>. The program runs and waits for a client to connect at port 20000.</p>

                <p>Here's the code for the Date Time Client - <strong>p069dtclient.rb</strong></p>
                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                # p069dtclient.rb
                require 'socket'
                streamSock = TCPSocket.new( "127.0.0.1", 20000 )
                #streamSock.send( "Hello\n" )
                str = streamSock.recv( 100 )
                print str
                streamSock.close
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p><strong>Explanation of p069dtclient.rb code</strong>:</p>

                <p>You first load the socket library with the <strong>require</strong> command. The statement <strong>sock = TCPSocket.new('127.0.0.1', 20000)</strong> opens a TCP connection to localhost on port 20000. The statement <strong>str = sock.recv(100)</strong> receives up to 100 bytes from sock. We display the date-time string received from the server and finally we close the socket.</p>

                <h3>Summary</h3>

                <p>This topic has explored the classes that make networking application development possible in Ruby. It discussed the basic classes for sockets programming (such as the <strong>Socket</strong> class) and also the classes that help to simplify sockets programming in Ruby, such as <strong>TCPSocket</strong> and <strong>TCPServer</strong>.</p>

                <p style="background-color: #FAFAFA; padding: 5px; margin-top: 20px; font-size: 65%;"><strong>Note</strong>: The Ruby Logo is Copyright (c) 2006, Yukihiro Matsumoto. I have made extensive references to information, related to Ruby, available in the public domain (wikis and the blogs, articles of various <span style="font-weight: bold;" title="Click Gurus on the menu above">Ruby Gurus</span>), my acknowledgment and thanks to all of them. Much of the material on <a href="/">rubylearning.github.io</a> and in the course at <a href="http://rubylearning.org/">rubylearning.org</a> is drawn <strong>primarily</strong> from the <strong>Programming Ruby book</strong>, available from <a href="http://pragprog.com/titles/ruby3/programming-ruby-3">The Pragmatic Bookshelf</a>.</p>

            </div>
            <!-- main inner ends here -->
        </div>

            <div id="rightbar">

            </div>

    <!-- content-wrap ends here -->
    </div>

<!-- wrap ends here -->
</div>

<!-- footer starts here -->
<div id="footer">
    <!-- CHANGE THE FOOTER -->
    <p>&copy; 2006-2021 <strong>rubylearning.github.io - A Ruby Tutorial</strong>&nbsp;&nbsp;Page Updated: 5th Jan. 2021 | Design: <a href="mailto:ealigam@gmail.com">Erwin Aligam</a> | Valid: <a href="http://validator.w3.org/check/referer">XHTML</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/">Home</a> | <a href="/privacy.html">Privacy</a> | <a href="/sitemap.html">Sitemap</a></p>

</div>

<!-- footer ends here -->

<!-- SyntaxHighlighter code -->
<script src="/js/shCore.js" type="text/javascript"></script>
<script src="/js/shBrushRuby.js" type="text/javascript"></script>
<script type="text/javascript">
dp.SyntaxHighlighter.HighlightAll('code');
</script>
<!-- SyntaxHighlighter code -->
</body>
</html>
